//package com.quectel.dms.service.aiotap;
//
//import cn.hutool.crypto.digest.DigestUtil;
//import com.fasterxml.jackson.databind.JsonNode;
//import com.quectel.util.common.JacksonUtils;
//import com.sun.jna.Memory;
//import com.sun.jna.Native;
//import com.sun.jna.Pointer;
//import com.sun.jna.Structure;
//import com.sun.jna.ptr.PointerByReference;
//import lombok.Data;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.stereotype.Component;
//
//import java.io.FileOutputStream;
//import java.io.IOException;
//import java.text.SimpleDateFormat;
//import java.util.*;
//import java.util.concurrent.ConcurrentHashMap;
//import java.util.concurrent.TimeUnit;
//
//
//@Slf4j
//@Component
//public class SDKInitUnit {
//    private static String devUrl = "tcp://10.88.107.14:9090?user=admin&password=admin123";
//    private static String activePwd = "b4hmegvii123"; //B4H固定激活密钥（B4H V2.0.1以上版本支持）
//    private final static String activeSvrUrl = "tcp://0.0.0.0:5555";
//    private final static String redirectUrl = "tcp://0.0.0.0:6666";
//    private final static boolean needRedirect = false;
//    private final static int needActiveServer = 0;
//    public static boolean sdkInited = false;
//    public final static Map<String, Pointer> devPool = new HashMap<>();
//    private static String accessPwd = "admin123";
//    private static Map<String, Boolean> activeStatePool = new HashMap<>();
//    public static ConcurrentHashMap<Pointer, AlarmCb> alarmCbPool = new ConcurrentHashMap<>();
//    public static ConcurrentHashMap<Pointer, AlarmCbUsrArg> alarmUsrArgPool = new ConcurrentHashMap<>();
////    public static ConcurrentHashMap<Pointer, MediaVideoTest.MediaVideoStreamCb> videoCbPool = new ConcurrentHashMap<>();
////    public static ConcurrentHashMap<Pointer, MediaVideoTest.MediaVideoStreamCbUsrArg> videoUsrArgPool = new ConcurrentHashMap<>();
////    public static ConcurrentHashMap<Pointer, MediaVideoTest.MediaIntelligentStreamCb> intelliCbPool = new ConcurrentHashMap<>();
////    public static ConcurrentHashMap<Pointer, MediaVideoTest.MediaIntelligentStreamCbUsrArg> intelliUsrArgPool = new ConcurrentHashMap<>();
////    public static ConcurrentHashMap<Pointer, MediaAudioTest.MediaAudioStreamCb> audioCbPool = new ConcurrentHashMap<>();
////    public static ConcurrentHashMap<Pointer, MediaAudioTest.MediaAudioStreamCbUsrArg> audioUsrArgPool = new ConcurrentHashMap<>();
////    public static ConcurrentHashMap<Pointer, MediaMixStream.MediaMixStreamCb> mixCbPool = new ConcurrentHashMap<>();
////    public static ConcurrentHashMap<Pointer, MediaPictureTest.MediaPictureCb> picCbPool = new ConcurrentHashMap<>();
//
//    public static void sdkInit() {
//        if (sdkInited) {
//            throw new RuntimeException("Sdk has been inited!");
//        }
//
//        PointerByReference outJsonPtr = new PointerByReference();
//        int ret = AiotapLibrary.INSTANTCE.AIOTAP_GetSdkInfo(outJsonPtr);
//        if (ret != AiotapError.ERROR_OK.getCode())
//        {
//            throw new RuntimeException("Get sdk info fail!");
//        }
//
//        String outJsonStr = outJsonPtr.getValue().getString(0);
//        AiotapLibrary.INSTANTCE.AIOTAP_Free(outJsonPtr.getValue());
//        log.debug("sdk info: " + outJsonStr);
//
//        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
//        Date currentDate = new Date();
//        String currentDateStr = sdf.format(currentDate);
//
//        AiotapLibrary.MegConnLogParamStruct logparm = new AiotapLibrary.MegConnLogParamStruct();
//        logparm.async = 0;
//        logparm.pattern = null;
//        logparm.consoleLevel = AiotapLibrary.LOG_LEVEL_INFO;
//        logparm.memoryPath = null;
//        logparm.flashPath = System.getProperty("user.dir") + "/logs/sdk_" + currentDateStr + ".log";
//        logparm.flashLevel = AiotapLibrary.LOG_LEVEL_INFO;
//
//        ret = AiotapLibrary.INSTANTCE.AIOTAP_SetLogParam(logparm);
//        if (ret != AiotapError.ERROR_OK.getCode())
//        {
//            throw new RuntimeException("set log param fail!");
//        }
//
//        AiotapLibrary.ConnInitParamStruct initParam = new AiotapLibrary.ConnInitParamStruct();
//        initParam.cliStatusCb = (handle, status, urlOrSsid) -> {
//            log.debug("url={} status={}", urlOrSsid, status);
//            if (status == AiotapLibrary.AIOT_DEVCIE_STATUS_LOGOUT) {
//                devPool.remove(urlOrSsid);
//            }
//        };
//
//        initParam.comFree = (p) -> {
//            long peer = Pointer.nativeValue(p);
//            Native.free(peer);
//        };
//
//        if (needActiveServer == 0)
//        {
//            initParam.regCheckCb = null;
//            initParam.activateCb = null;
//        }
//        else // 主动模式时，需要注册设备注册回调，平台在该处判断是否允许设备接入。同一台设备，只有第一次上线时才会调用注册回调。
//        {
//            Map<String, Object> paramJson = new HashMap<>();
//            paramJson.put("active_server_url", activeSvrUrl);
//            initParam.param = JacksonUtils.toJsonString(paramJson);
//            initParam.regCheckCb = (handle, url, activeParam, outParam) -> {
//                if (!sdkInited)
//                {
//                    return 0;
//                }
//                JsonNode inJson = JacksonUtils.parse(activeParam);
//                String sn = inJson.get("sn").asText();
//                //登录校验
//                if (activeStatePool.containsKey(sn) && activeStatePool.get(sn)==false){
//                    return 0;
//                }
//                if (inJson.has("pwd_encrypto")) {
//                    if (!inJson.has("salt") || !inJson.has("challenge")) {
//                        log.debug("invalid activeParam of sn:{}", sn);
//                        return 0;
//                    }
//                    String salt = inJson.get("salt").asText();
//                    String challenge = inJson.get("challenge").asText();
//                    String keyHex = DigestUtil.sha256Hex(accessPwd + salt + challenge);
//                    if (!keyHex.equals(inJson.get("pwd_encrypto").asText())) {
//                        log.debug("invalid accessPwd of sn:{}", sn);
//                        return 0;
//                    }
//                }
//                if (needRedirect) {
//                    String outParamStr = redirectUrl;
//                    Pointer ptr = new Memory(outParamStr.length() + 1);
//                    ptr.setString(0, outParamStr);
//                    outParam.setValue(ptr);
//                    Pointer.nativeValue(ptr, 0);
//                    log.info("url=" + url + " activeParam=" + activeParam + " redirectUrl=" + redirectUrl);
//                    return 0;
//                }
//                log.info("url=" + url + " activeParam=" + activeParam);
//                devPool.put(url, handle);
//                return 1;
//            };
//
//            initParam.activateCb = (inParam, outParam) -> {
//                log.info("activeCb inParam: {}", inParam);
//                //激活校验
//                JsonNode inJson = JacksonUtils.parse(inParam);
//                String sn = inJson.get("sn").asText();
//                if (!inJson.has("salt") || !inJson.has("challenge") || !inJson.has("pwd_encrypto")){
//                    log.debug("invalid active inParam of {}", inJson.get("sn").asText());
//                    return AiotapError.ERROR_INVALID_USER_OR_PWD.getCode();
//                }
//                String salt = inJson.get("salt").asText();
//                String challenge = inJson.get("challenge").asText();
//                String keyHex = DigestUtil.sha256Hex(activePwd + salt + challenge);
//                if (!keyHex.equals(inJson.get("pwd_encrypto").asText())) {
//                    activeStatePool.put(sn, false);
//                    log.debug("invalid activePwd of sn:{}", inJson.get("sn").asText());
//                    return AiotapError.ERROR_INVALID_PARAM.getCode();
//                }
//                activeStatePool.put(sn, true);
//                Map<String, Object> outParamJson = new HashMap();
//                outParamJson.put("access_pwd", accessPwd);
//                outParamJson.put("activate_pwd", activePwd);
//                String outParamStr = outParamJson.toString();
//                Pointer ptr = new Memory(outParamStr.length() + 1);
//                ptr.setString(0, outParamStr);
//                outParam.setValue(ptr);
//                Pointer.nativeValue(ptr, 0);
//                log.info("activateCb outParam = " + outParam.getValue().getString(0));
//
//                return 0;
//            };
//        }
//
//        ret = AiotapLibrary.INSTANTCE.AIOTAP_Init(initParam);
//        log.debug("sdk init ret:" + ret);
//
//        sdkInited = true;
//    }
//
//    public static void sdkUnInit() {
//        if (sdkInited) {
//            sdkInited = false;
//
//            devPool.forEach((url, handle)->{
//                AiotapLibrary.INSTANTCE.AIOTAP_Logout(handle);});
//
//            AiotapLibrary.INSTANTCE.AIOTAP_Uninit();
//        }
//    }
//
//    public static Pointer getDevice() throws AiotapException {
//        if (!devPool.containsKey(devUrl))
//        {
//            log.error("device {} isn't exist!", devUrl);
//            throw new AiotapException(AiotapError.ERROR_GENERAL);
//        }
//
//        return devPool.get(devUrl);
//    }
//
//    public static Pointer getDevice(String url) throws AiotapException {
//        if (!devPool.containsKey(url))
//        {
//            log.error("device {} isn't exist!", url);
//            throw new AiotapException(AiotapError.ERROR_NOT_SUPPORT);
//        }
//
//        return devPool.get(devUrl);
//    }
//
//    public static void login(String url) throws AiotapException {
//        if (needActiveServer == 1)
//        {
//            log.error("active server login isn't support!");
//            throw new AiotapException(AiotapError.ERROR_NOT_SUPPORT);
//        }
//
//        PointerByReference phandle = new PointerByReference();
//        int ret = AiotapLibrary.INSTANTCE.AIOTAP_Login(url, phandle);
//        if (ret != 0)
//        {
//            log.error("login device {} fail!", url);
//            throw new AiotapException(AiotapError.fromInt(ret));
//        }
//
//        Pointer handle = phandle.getValue();
//        devPool.put(url, handle);
//    }
//
//    public static void login() throws AiotapException {
//        // 主动模式时，等待设备注册上线,等待时间为10秒
//        if (needActiveServer == 1)
//        {
//            //等待设备主动注册时间
//            waitMs(10000);
//
//            if (devPool.isEmpty())
//            {
//                log.error("not support active login");
//                throw new AiotapException(AiotapError.ERROR_GENERAL);
//            }
//
//            for (Map.Entry<String, Pointer> entry : devPool.entrySet()) {
//                devUrl = entry.getKey();
//                break;
//            }
//        }
//        else
//        {
//            login(devUrl);
//        }
//    }
//
//    public static void loginOut(String url) throws AiotapException {
//        if (!devPool.containsKey(url))
//        {
//            return;
//        }
//
//        devPool.remove(url);
//        int ret = AiotapLibrary.INSTANTCE.AIOTAP_Logout(devPool.get(url));
//        if (ret != 0)
//        {
//            log.error("logout device {} fail!", url);
//            throw new AiotapException(AiotapError.fromInt(ret));
//        }
//    }
//
//    public static void loginOut() throws AiotapException {
//        loginOut(devUrl);
//    }
//
//    public static class AlarmCb implements AiotapLibrary.AlarmCb {
//        @Override
//        public void invoke(AiotapLibrary.AlarmMsg.ByReference alarmMsg, Pointer userArg) {
//            AlarmCbUsrArg alarmUserArg = new AlarmCbUsrArg(userArg);
//            alarmUserArg.read();
//            log.debug("handle: {}", alarmUserArg.getHandle());
//
//            byte[] info = alarmMsg.jsonInfo.getByteArray(0, alarmMsg.infoLen);
//            String infoStr = new String(info);
//            log.debug("info: " + infoStr);
//            log.debug("binDataNumSize: " + alarmMsg.data.binDataInfoNum);
//            log.debug("type: " + alarmMsg.data.binDataInfos.type);
//
//            AiotapLibrary.BinDataInfo[] binDataInfos = (AiotapLibrary.BinDataInfo[])alarmMsg.data.binDataInfos.toArray(alarmMsg.data.binDataInfoNum);
//
//            for (AiotapLibrary.BinDataInfo binDataInfo : binDataInfos)
//            {
//                log.debug("binDataInfos: " + binDataInfo.size);
//
//                byte[] data = binDataInfo.binData.getByteArray(0, binDataInfo.size);
//                try {
//                    FileOutputStream fos;
//                    fos = new FileOutputStream("pic.jpg", false);
//                    fos.write(data);
//                    fos.close();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            }
//        }
//    }
//
//    @Data
//    public static class AlarmCbUsrArg extends Structure {
//        public Pointer handle;
//
//        public AlarmCbUsrArg() {
//            super();
//        }
//
//        public AlarmCbUsrArg(Pointer p) {
//            super(p);
//        }
//
//        @Override
//        protected List<String> getFieldOrder() {
//            return Arrays.asList("handle");
//        }
//
//        public static class ByReference extends AlarmCbUsrArg implements Structure.ByReference {
//        }
//
//        public static class ByValue extends AlarmCbUsrArg implements Structure.ByValue {
//        }
//    }
//
//    private static void waitMs(int ms) {
//        try {
//            TimeUnit.MILLISECONDS.sleep(ms);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
//    }
//}
